package folder.main.exp0.controllers.linearProgramming.bandwidth.traffic;

import java.util.LinkedHashMap;

import folder.main.exp0.controllers.linearProgramming.bandwidth.GAB;
import folder.main.exp0.linksMapping.ShortestPath;
import folder.model.link.Link;
import folder.model.network.Network;
import folder.model.node.Node;
import folder.model.virtual.VirtualLink;
import folder.model.virtual.VirtualNetwork;
import folder.model.virtual.VirtualNode;

public abstract class GABT extends GAB
{
	public GABT( Network network, double[][] delays, int T )
	{
		super( network, delays, T );
	}
	
	protected void fillTraffic( int bandwidth )
	{
		ShortestPath shortestPath = new ShortestPath( "ShortestPath" );
		shortestPath.setCostMetric( ShortestPath.DISTANCE_COST );
		shortestPath.setBackupVirtualNetwork( false );
		
		VirtualNetwork vNetwork = VirtualNetwork.virtualNetwork( 0 );
		VirtualNode vNodeA = VirtualNode.virtualNode( 0, vNetwork );
		VirtualNode vNodeB = VirtualNode.virtualNode( 1, vNetwork );
		VirtualLink vLink = VirtualLink.virtualLink( 0, bandwidth, vNodeA, vNodeB,vNetwork );
		vNodeA.addVirtualLink(vLink);
		vNodeB.addVirtualLink(vLink);
		
		vNetwork.addVirtualNode( vNodeA );
		vNetwork.addVirtualNode( vNodeB );
		vNetwork.addVirtualLink( vLink );
		
		for( Node nodeA: network.getNodes() )
			for( Node nodeB: network.getNodes() )
				if( nodeA.getIdentifier() < nodeB.getIdentifier() )
				{
					LinkedHashMap< VirtualNode, Node > mapping = new LinkedHashMap< VirtualNode, Node >();
					mapping.put( vNodeA, nodeA );
					mapping.put( vNodeB, nodeB );
					
					double shortestPaths[][][][] = shortestPath.run( vNetwork, network, mapping );
					
					if( shortestPaths != null )
					{
						for( int i = 0; i < vNetwork.getNumberVirtualLinks(); i++ )
							for( int j = 0; j < network.getNumberNodes(); j++ )
								for( int k = 0; k < network.getNumberNodes(); k++ )
									if( shortestPaths[ i ][ j ][ k ][ 0 ] != 0 )
									{
										VirtualLink vLinkI = null;
										
										for( VirtualLink virtualLink: vNetwork.getVirtualLinks() )
											if( i == virtualLink.getIdentifier() ){
												vLinkI = virtualLink; break; }
										
										Node nodeJ = null;
																					
										for( Node node: network.getNodes() )
											if( node.getIdentifier() == j ){
												nodeJ = node; break; }
										
										Node nodeK = null;
										
										for( Node node: network.getNodes() )
											if( node.getIdentifier() == k ){
												nodeK = node; break; }
										
										for( Link link: network.getLinks() )
											if( link.getNodeA().equals( nodeJ ) && link.getNodeB().equals( nodeK ) ||
												link.getNodeA().equals( nodeK ) && link.getNodeB().equals( nodeJ ) )
										{
											link.allocateBandwidthAvailable( vLinkI.getBandwidth() );
											break;
										}
									}
					}
				}
	}
	
	protected void emptyTraffic()
	{
		for( Link link: this.network.getLinks() )
			link.resetBandwidthAvailable();
	}

}

